package com.crazy.crazyuserservice.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.crazy.crazycommon.common.ErrorCode;
import com.crazy.crazycommon.constant.ClientConstan;
import com.crazy.crazycommon.exception.BusinessException;
import com.crazy.crazymodel.model.dto.admin.AddAccountRequest;
import com.crazy.crazymodel.model.dto.admin.ReChargeRequest;
import com.crazy.crazymodel.model.dto.admin.UpdateCustomerInfoRequest;
import com.crazy.crazymodel.model.entity.BankCard;
import com.crazy.crazymodel.model.entity.Customer;
import com.crazy.crazymodel.model.vo.*;
import com.crazy.crazyuserservice.mapper.ClientMapper;
import com.crazy.crazyuserservice.service.ClientService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
@Slf4j
public class ClientServiceImpl extends ServiceImpl<ClientMapper, Customer> implements ClientService {

    @Resource
    private ClientMapper clientMapper;

    /**
     * 新增用户
     *
     * @param addAccountRequest
     * @return
     */
    @Transactional
    @Override
    public AddCustomerVO save(AddAccountRequest addAccountRequest) {
        try {
            //检验该用户是否已经开户
            if (clientMapper.getCustomerIdByCardNumber(addAccountRequest.getIdNumber()) != null)
                return null;
        } catch (SQLException e) {
            log.error("数据库异常", e);
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "数据库异常");
        }

        Customer customer = new Customer();
        List<BankCard> bankCards = new ArrayList<BankCard>();

        //对象属性拷贝
        BeanUtils.copyProperties(addAccountRequest, customer);
        for(BankCard card: addAccountRequest.getBankCards()){
            BankCard newcard = new BankCard();
            BeanUtils.copyProperties(card, newcard);
            //设置创建时间及更新时间
            newcard.setCreateTime(new Date(System.currentTimeMillis()));
            newcard.setUpdateTime(new Date(System.currentTimeMillis()));
            newcard.setBalance(card.getBalance() == null ? BigDecimal.valueOf(0) : card.getBalance());

            bankCards.add(newcard);
        }

        //设置总资产
        customer.setTotalAssets(BigDecimal.valueOf(0));

        //设置开户时间
        customer.setOpenTime(new Date(System.currentTimeMillis()));

        //封装返回结果
        AddCustomerVO addCustomerVO = new AddCustomerVO();

        try{
            //插入数据库
            clientMapper.insertAccount(customer);
            //获取客户ID
            Integer id = clientMapper.getCustomerIdByCardNumber(customer.getIdNumber());
            for(BankCard card: bankCards) {
                //设置客户ID
                card.setCustomerID(id);
                clientMapper.insertBankCard(card);
                clientMapper.insertBankCardBalance(card);
            }
            addCustomerVO.setId(id);
        }catch (SQLException e){
            log.error("数据库异常", e);
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "数据库异常");
        }

        return addCustomerVO;
    }

    /**
     * 模拟充值
     * @param reChargeRequest
     */
    @Transactional
    @Override
    public BigDecimal recharge(ReChargeRequest reChargeRequest){
        try {
            if (clientMapper.getByBankCardNumber(reChargeRequest.getBankCardNumber()) == null)
                return null;
            BankCard card = new BankCard();
            BeanUtils.copyProperties(reChargeRequest, card);
            clientMapper.recharge(card);
            return clientMapper.getMoney(card.getBankCardNumber());
        } catch (SQLException e) {
            log.error("数据库异常", e);
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "数据库异常");
        }
    }

    /**
     * 查询银行卡账户余额
     * @param bankcard
     * @return
     */
    @Transactional
    @Override
    public GetMoneyVO getMoney(String bankcard){
        GetMoneyVO getMoneyVO = new GetMoneyVO();

        try {
            if (clientMapper.getByBankCardNumber(bankcard) == null)
                return null;
            //封装返回结果
            getMoneyVO.setBalance(clientMapper.getMoney(bankcard));
        } catch (SQLException e) {
            log.error("数据库异常", e);
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "数据库异常");
        }

        return getMoneyVO;
    }

    /**
     * 获取客户信息列表
     * @param current
     * @param name
     * @return
     */
    @Transactional
    @Override
    public AllCustomerVO pageQuery(Integer current, String name){
        //若name为空则转换为”“
        name = name == null ? "" : name;

        //模糊查询所有符合的用户
        ArrayList<Customer> all = null;
        try {
            all = clientMapper.getByCustomerName(name);
        } catch (SQLException e) {
            log.error("数据库异常", e);
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "数据库异常");
        }
        log.info("模糊查询结果：" + all);
        //若页码不合理则返回空
        if (current <= 0 || (current - 1) * ClientConstan.NUMBEROFPAGE + 1 > all.size())
            return null;

        //截取该页查询结果
        ArrayList<Customer> result;
        if (current * ClientConstan.NUMBEROFPAGE > all.size())
            result = new ArrayList<Customer>(all.subList((current - 1) * ClientConstan.NUMBEROFPAGE, all.size()));
        else
            result = new ArrayList<Customer>(all.subList((current - 1) * ClientConstan.NUMBEROFPAGE, (current - 1) * ClientConstan.NUMBEROFPAGE + ClientConstan.NUMBEROFPAGE));

        //拷贝用户信息和银行卡信息
        ArrayList<CustomerVO> resultAll = new ArrayList<>();
        try {
            for(Customer customer: result){
                //拷贝用户基本信息
                CustomerVO customerVO = new CustomerVO();
                BeanUtils.copyProperties(customer, customerVO);
                //拷贝该用户的银行卡信息
                ArrayList<BankCard> bankCards = clientMapper.getBankCardByCustomerID(customer.getCustomerID());
                ArrayList<BankCardVO> bankCardVOs = new ArrayList<>();
                for(BankCard card: bankCards){
                    BankCardVO bankCardVO = new BankCardVO();
                    BeanUtils.copyProperties(card, bankCardVO);
                    bankCardVO.setBalance(clientMapper.getMoney(card.getBankCardNumber()));
                    bankCardVOs.add(bankCardVO);
                }
                customerVO.setBankCards(bankCardVOs);

                resultAll.add(customerVO);
            }
        } catch (SQLException e) {
            log.error("数据库异常", e);
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "数据库异常");
        }

        //封装返回参数
        AllCustomerVO allCustomerVO = new AllCustomerVO();
        allCustomerVO.setCurrent(current);
        allCustomerVO.setSize(ClientConstan.NUMBEROFPAGE);
        allCustomerVO.setTotal(resultAll.size());
        allCustomerVO.setAccounts(resultAll);
        return allCustomerVO;
    }

    /**
     * 获取全部客户列表
     * @return
     */
    @Transactional
    @Override
    public AllCustomerVO getAllCustomer(){
        //获取全部用户基本信息
        ArrayList<Customer> customers = null;
        ArrayList<CustomerVO> resultAll = new ArrayList<>();
        try {
            customers = clientMapper.getAllCustomer();
            for(Customer customer: customers){
                //拷贝用户基本信息
                CustomerVO customerVO = new CustomerVO();
                BeanUtils.copyProperties(customer, customerVO);
                //拷贝该用户的银行卡信息
                ArrayList<BankCard> bankCards = clientMapper.getBankCardByCustomerID(customer.getCustomerID());
                ArrayList<BankCardVO> bankCardVOs = new ArrayList<>();
                for(BankCard card: bankCards){
                    BankCardVO bankCardVO = new BankCardVO();
                    BeanUtils.copyProperties(card, bankCardVO);
                    bankCardVO.setBalance(clientMapper.getMoney(card.getBankCardNumber()));
                    bankCardVOs.add(bankCardVO);
                }
                customerVO.setBankCards(bankCardVOs);

                resultAll.add(customerVO);
            }
        } catch (SQLException e) {
            log.error("数据库异常", e);
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "数据库异常");
        }

        //封装返回参数
        AllCustomerVO allCustomerVO = new AllCustomerVO();
        allCustomerVO.setCurrent(1);
        allCustomerVO.setSize(ClientConstan.NUMBEROFPAGE);
        allCustomerVO.setTotal(resultAll.size());
        allCustomerVO.setAccounts(resultAll);
        return allCustomerVO;
    }

    /**
     * 修改客户信息
     * @param updateCustomerInfoRequest
     */
    @Transactional
    @Override
    public boolean update(UpdateCustomerInfoRequest updateCustomerInfoRequest){
        try {
            //判断用户ID是否存在
            if (clientMapper.getByCustomerID(updateCustomerInfoRequest.getCustomerID()) == null)
                return false;
        } catch (SQLException e) {
            log.error("数据库异常", e);
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "数据库异常");
        }

        Customer customer = new Customer();
        List<BankCard> bankCards = new ArrayList<BankCard>();
        log.info("修改客户信息{}", updateCustomerInfoRequest);
        //对象属性拷贝
        BeanUtils.copyProperties(updateCustomerInfoRequest, customer);
        log.info("修改客户信息{}", customer);
        for(BankCard card: updateCustomerInfoRequest.getBankCards()){
            BankCard newcard = new BankCard();
            BeanUtils.copyProperties(card, newcard);
            //设置客户ID
            newcard.setCustomerID(customer.getCustomerID());
            //设置创建时间及更新时间
            newcard.setCreateTime(new Date(System.currentTimeMillis()));
            newcard.setUpdateTime(new Date(System.currentTimeMillis()));
            newcard.setBalance(card.getBalance() == null ? BigDecimal.valueOf(0) : card.getBalance());

            bankCards.add(newcard);
        }

        try {
            //从数据库中删除不需要的银行卡信息
            ArrayList<BankCard> bankCards_before = clientMapper.getBankCardByCustomerID(customer.getCustomerID());

            log.info("获取全部客{}", bankCards);
            for (BankCard card: bankCards_before){
                boolean del = true;
                //检查银行卡是否要删除
                for (BankCard card_now: bankCards)
                    if (card.getBankCardNumber().equals(card_now.getBankCardNumber())){
                        log.info("获取全部客表{}", card);
                        del = false;
                        break;
                    }
                //删除银行卡
                if(del)
                    clientMapper.deleteBankCardById(card.getBankCardID());
            }

            //更新数据库
            clientMapper.updateAccount(customer);
            for(BankCard card: bankCards){
                if (clientMapper.getByBankCardNumber(card.getBankCardNumber()) != null)
                    clientMapper.updateBankCard(card);
                else {
                    clientMapper.insertBankCard(card);
                    clientMapper.insertBankCardBalance(card);
                }
            }
        } catch (SQLException e) {
            log.error("数据库异常", e);
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "数据库异常");
        }

        return true;
    }

    /**
     * 删除客户
     * @param id
     */
    @Transactional
    @Override
    public boolean deleteAccount(Integer id){
        try {
            //判断用户ID是否存在
            if (clientMapper.getByCustomerID(id) == null)
                return false;
            //从数据库中获取该用户的所有银行卡信息
            List<BankCard> bankCards = clientMapper.getBankCardByCustomerID(id);

            //从数据库中删除银行卡
            for(BankCard card: bankCards)
                clientMapper.deleteAllCardsByAccountId(card.getBankCardID());

            //删除用户信息
            clientMapper.deleteAccountById(id);
        } catch (SQLException e) {
            log.error("数据库异常", e);
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "数据库异常");
        }

        return true;
    }

    /**
     * 删除客户银行卡
     * @param bankcard
     */
    @Transactional
    @Override
    public boolean deleteBankCard(String bankcard){
        try {
            // 判断银行卡号是否存在
            if (clientMapper.getByBankCardNumber(bankcard) == null)
                return false;

            clientMapper.deleteBankCardByCard(bankcard);
        } catch (SQLException e) {
            log.error("数据库异常", e);
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "数据库异常");
        }

        return true;
    }

    /**
     * 查看客户银行卡是否能删除
     * @param bankcards
     */
    @Transactional
    @Override
    public DelCardsVO checkCarddel(ArrayList<String> bankcards){
        DelCardsVO delCardsVO = new DelCardsVO();
        ArrayList<String> result = new ArrayList<>();

        try {
            for (String card: bankcards){
                // 筛选出不具有份额的银行卡
                if (clientMapper.checkCarddel(card).isEmpty())
                    result.add(card);
            }
        } catch (SQLException e) {
            log.error("数据库异常", e);
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "数据库异常");
        }

        //封装数据传回
        delCardsVO.setCards(result);

        return delCardsVO;
    }

    /**
     * 根据客户姓名和idNumber获取客户
     * @param name
     * @param idNumber
     * @return
     */
    @Override
    public Customer getByNameAndIdNumber(String name, String idNumber) {
        QueryWrapper<Customer> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("name",name);
        queryWrapper.eq("idNumber",idNumber);
        Customer customer = clientMapper.selectOne(queryWrapper);
        return customer;
    }
}
